import os
from django.db.models import Count
from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt
from django.http import JsonResponse, HttpResponse
from question.models import *
from submission.models import Submission
from question.serializers import *
from django.utils import timezone
from backend.tools import *
import random
import json
from django.contrib.auth.models import User
from question.coder import encoder


@csrf_exempt
def modifySettings(request):
    if request.method == 'POST':
        data = json.loads(request.body)
        if 'id' not in data:
            return JsonResponse({"Message": "Need questionnaire id"}, safe=False)
        if 'Settings' not in data:
            return JsonResponse({"Message": "Need Settings"}, safe=False)
        qid = data['id']
        username = data.get('username')
        if username:
            try:
                user = User.objects.get(username=username)
            except:
                return JsonResponse({'Message': 'User Does Not Exist'}, safe=False)
        else:
            return JsonResponse({'Message': 'Please Login'}, safe=False)
        try:
            questionnaire = Questionnaire.objects.get(id=qid, CreateUser=user.id)
        except Questionnaire.DoesNotExist:
            return JsonResponse({"Message": "No Such Questionnaire"}, safe=False)
        data = data["Settings"]
        settingsS = SettingsSerializer(instance=questionnaire.Settings,data=data)
        if settingsS.is_valid():
            settingsS.save()
        else:
            print(settingsS.errors)
            return JsonResponse({"Message": "Arguments Illegal"}, safe=False)
        return JsonResponse({"Message": "Success"}, safe=False)


@csrf_exempt
def getQuestionnaire(request):
    if request.method == 'POST':
        data = json.loads(request.body)
        if 'username' in data:
            username = data['username']
        else:
            return JsonResponse({'Message': 'Need CreateUser'}, safe=False)
        Open = None
        if 'Open' in data:
            Open = data['Open']
        if username:
            try:
                user = User.objects.get(username=username)
            except User.DoesNotExist:
                return JsonResponse({'Message': 'User Does Not Exist'}, safe=False)
        else:
            return JsonResponse({'Message': 'Need CreateUser'}, safe=False)
        q_list = Questionnaire.objects.filter(CreateUser=user)
        qs = []
        for q in q_list:
            checkQuestionnaireTime(q)
            if Open is None or Open == q.Open:
                qInfo = q.to_dict()
                nums = q.submission_set.filter(isSubmitted=True).aggregate(num=Count('id'))
                qInfo['Submission'] = nums['num']
                qs.append(qInfo)
        return JsonResponse({'Questionnaire': qs}, safe=False)


@csrf_exempt
def manageQuestionnaire(request):
    if request.method == 'POST':
        data = json.loads(request.body)
        if 'CreateUser' in data:
            username = data['CreateUser']
        else:
            return JsonResponse({'Message': 'Need CreateUser'}, safe=False)
        if username:
            try:
                user = User.objects.get(username=username)
            except User.DoesNotExist:
                return JsonResponse({'Message': 'User Does Not Exist'}, safe=False)
        else:
            return JsonResponse({'Message': 'Need CreateUser'}, safe=False)
        q_list = Questionnaire.objects.filter(CreateUser=user)
        qs = []
        for q in q_list:
            checkQuestionnaireTime(q)
            qInfo = q.to_dict(exclude=["Question"])
            nums = q.submission_set.filter(isSubmitted=True).aggregate(num=Count('id'))
            qInfo['Submission'] = nums['num']
            qs.append(qInfo)
        return JsonResponse({'Questionnaire': qs}, safe=False)


@csrf_exempt
def answerQuestionnaire(request):
    if request.method == 'POST':
        data = json.loads(request.body)
        if 'EncodeID' not in data:
            return JsonResponse({'Message': 'Need EncodeID'}, safe=False)
        encodeID = data['EncodeID']
        byteID = encoder.decrypt(encodeID)
        qid = int(byteID)
        print(qid)
        try:
            q = Questionnaire.objects.get(id=qid)
        except Questionnaire.DoesNotExist:
            return JsonResponse({'Message': 'Questionnaire is closed'}, safe=False)
        if 'Mode' in data and data['Mode'] == 'preview':
            return JsonResponse({'Questionnaire': q.to_dict()}, safe=False)
        checkQuestionnaireTime(q)
        if not q.Open:
            return JsonResponse({'Message': 'Questionnaire is closed'}, safe=False)
        # 添加时间判断
        if q.Type == 4 and q.Settings.Reorder:
            if 'ip' in data:
                ip = data['ip']
                num = 0
                for c in ip:
                    num = num + ord(c)
                q_list = []
                for question in q.Question.all():
                    q_list.append(question.Number)
                random.seed(num)
                random.shuffle(q_list)
                return JsonResponse({'Questionnaire': q.to_dict(), 'NumberList': q_list}, safe=False)
        return JsonResponse({'Questionnaire': q.to_dict()}, safe=False)


@csrf_exempt
def createQuestionnaire(request):
    if request.method == 'POST':
        data = json.loads(request.body)
        username = data.get('username')
        if username:
            try:
                user = User.objects.get(username=username)
            except:
                return JsonResponse({'Message': 'User Does Not Exist'}, safe=False)
        else:
            return JsonResponse({'Message': 'Please Login'}, safe=False)
        data['CreateUser'] = user.id
        data['CreateTime'] = timezone.now()
        data['UpdateTime'] = timezone.now()
        questionnaireS = QuestionnaireSerializer(data=data)
        if questionnaireS.is_valid():
            questionnaire = questionnaireS.save()
            data.clear()
            data['EncodeID'] = encoder.encrypt(str(questionnaire.id))
            questionnaireS = QuestionnaireSerializer(instance=questionnaire, data=data)
            if questionnaireS.is_valid():
                questionnaire = questionnaireS.save()
            else:
                print(questionnaireS.errors)
                return JsonResponse({"Message": "Encode Failed"}, safe=False)
        else:
            print(questionnaireS.errors)
            return JsonResponse({"Message": "Arguments Illegal"}, safe=False)
        if questionnaire.Type == 2:
            question = Question.objects.create(Type=6, Stem='默认投票单选题', Questionnaire=questionnaire, Must=True, Number=0)
            question.save()
            choice = Choice.objects.create(Text='投票1', Question=question)
            choice.save()
            choice = Choice.objects.create(Text='投票2', Question=question)
            choice.save()
        elif questionnaire.Type == 3:
            question = Question.objects.create(Type=3, Stem='姓名', Questionnaire=questionnaire, Must=True, Number=0)
            question.save()
            question = Question.objects.create(Type=3, Stem='手机号', Questionnaire=questionnaire, Must=True, Number=1)
            question.save()
            question = Question.objects.create(Type=8, Stem='默认报名单选题', Questionnaire=questionnaire, Must=True, Number=2)
            question.save()
            choice = Choice.objects.create(Text='报名1', Times=10, Question=question)
            choice.save()
            choice = Choice.objects.create(Text='报名2', Times=10, Question=question)
            choice.save()
        elif questionnaire.Type == 4:
            question = Question.objects.create(Type=3, Stem='姓名', Questionnaire=questionnaire, Must=True, Number=0)
            question.save()
            question = Question.objects.create(Type=3, Stem='学号', Questionnaire=questionnaire, Must=True, Number=1)
            question.save()
        elif questionnaire.Type == 5:
            question = Question.objects.create(Type=3, Stem='姓名', Questionnaire=questionnaire, Must=True, Number=0)
            question.save()
            question = Question.objects.create(Type=3, Stem='学号', Questionnaire=questionnaire, Must=True, Number=1)
            question.save()
            question = Question.objects.create(Type=1, Stem='本日体温', Questionnaire=questionnaire, Must=True, Number=2)
            question.save()
            choice = Choice.objects.create(Text='小于36', Question=question)
            choice.save()
            choice = Choice.objects.create(Text='36-37.2', Question=question)
            choice.save()
            choice = Choice.objects.create(Text='大于37.2', Question=question)
            choice.save()
            question = Question.objects.create(Type=1, Stem='是否前往中高风险区', Questionnaire=questionnaire, Must=True, Number=3)
            question.save()
            choice = Choice.objects.create(Text='是', Question=question)
            choice.save()
            choice = Choice.objects.create(Text='否', Question=question)
            choice.save()
            question = Question.objects.create(Type=1, Stem='是否存在疑似症状', Questionnaire=questionnaire, Must=True, Number=4)
            question.save()
            choice = Choice.objects.create(Text='是', Question=question)
            choice.save()
            choice = Choice.objects.create(Text='否', Question=question)
            choice.save()
            question = Question.objects.create(Type=5, Stem='当前所在位置', Questionnaire=questionnaire, Must=True, Number=5)
            question.save()
        return JsonResponse({"id": questionnaire.id, "Message": "Success"}, safe=False)


@csrf_exempt
def modifyQuestionnaire(request):
    if request.method == 'POST':
        data = json.loads(request.body)
        if 'id' not in data:
            return JsonResponse({"Message": "Need questionnaire id"}, safe=False)
        if 'ReleaseTime' in data:
            del data['ReleaseTime']
        if 'UpdateTime' in data:
            del data['UpdateTime']
        qid = data['id']
        del data['id']
        username = data.get('username')
        if username:
            try:
                user = User.objects.get(username=username)
            except:
                return JsonResponse({'Message': 'User Does Not Exist'}, safe=False)
        else:
            return JsonResponse({'Message': 'Please Login'}, safe=False)
        try:
            questionnaire = Questionnaire.objects.get(id=qid, CreateUser=user.id)
        except Questionnaire.DoesNotExist:
            return JsonResponse({"Message": "No Such Questionnaire"}, safe=False)
        data['UpdateTime'] = timezone.now()
        if 'Settings' in data:
            newSettings = data['Settings']
            del data['Settings']
            settingsS = SettingsSerializer(instance=questionnaire.Settings, data=newSettings)
            if settingsS.is_valid():
                settingsS.save()
            else:
                print(settingsS.errors)
        questionnaireS = QuestionnaireSerializer(instance=questionnaire, data=data)
        if questionnaireS.is_valid():
            questionnaire = questionnaireS.save()
        else:
            print(questionnaireS.errors)
            return JsonResponse({"Message": "Arguments Illegal"}, safe=False)
        failed = []
        if 'Question' not in data:
            return JsonResponse({"Message": "Success"}, safe=False)
        for q in data['Question']:
            # 若将问题修改所属至另一答卷，则跳过
            if 'Questionnaire' in q and q['Questionnaire'] != questionnaire.id:
                continue
            q['Questionnaire'] = questionnaire.id
            try:
                # 若原问题存在且所属答卷与当前答卷符合，直接修改
                if 'id' in q:
                    question = Question.objects.get(id=q['id'], Questionnaire_id=questionnaire.id)
                    questionS = QuestionSerializer(instance=question, data=q)
                else:
                    questionS = QuestionSerializer(data=q)
            except Question.DoesNotExist:
                # 否则创建新问题并归属于当前答卷
                del q['id']
                questionS = QuestionSerializer(data=q)
            if questionS.is_valid():
                question = questionS.save()
                if 'Choice' not in q:
                    continue
                for c in question.Choice.all():
                    c.delete()
                for c in q['Choice']:
                    if 'id' in c:
                        del c['id']
                    c['Question'] = question.id
                    choiceS = ChoiceSerializer(data=c)
                    if choiceS.is_valid():
                        choiceS.save()
                    else:
                        print(choiceS.errors)
                        if q['Number'] not in failed:
                            failed.append(q['Number'])
            else:
                print(questionS.errors)
                failed.append(q['Number'])
            continue
        return JsonResponse({"Message": "Success", "FailedQuestion": failed}, safe=False)


@csrf_exempt
def deleteQuestionnaire(request):
    if request.method == 'POST':
        data = json.loads(request.body)
        if 'id' not in data:
            return JsonResponse({"Message": "Need questionnaire id"}, safe=False)
        qid = data['id']
        username = data.get('username')
        if username:
            try:
                user = User.objects.get(username=username)
            except:
                return JsonResponse({'Message': 'User Does Not Exist'}, safe=False)
        else:
            return JsonResponse({'Message': 'Please Login'}, safe=False)
        try:
            questionnaire = Questionnaire.objects.get(id=qid, CreateUser=user.id)
        except Questionnaire.DoesNotExist:
            return JsonResponse({"Message": "No Such Questionnaire"}, safe=False)
        questionnaire.delete()
        return JsonResponse({"Message": "Success"}, safe=False)


@csrf_exempt
def copyQuestionnaire(request):
    if request.method == 'POST':
        data = json.loads(request.body)
        if 'id' not in data:
            return JsonResponse({"Message": "Need questionnaire id"}, safe=False)
        qid = data['id']
        username = data.get('username')
        if username:
            try:
                user = User.objects.get(username=username)
            except:
                return JsonResponse({'Message': 'User Does Not Exist'}, safe=False)
        else:
            return JsonResponse({'Message': 'Please Login'}, safe=False)
        try:
            questionnaire = Questionnaire.objects.get(id=qid, CreateUser=user.id)
        except Questionnaire.DoesNotExist:
            return JsonResponse({"Message": "No Such Questionnaire"}, safe=False)
        title = questionnaire.Title + ' - 副本'
        if 'Title' in data:
            title = data['Title']
        data.clear()
        data = questionnaire.to_copy()
        data['CreateTime'] = timezone.now()
        data['UpdateTime'] = timezone.now()
        if questionnaire.Open:
            data['ReleaseTime'] = timezone.now()
        data['Title'] = title
        questionnaireS = QuestionnaireSerializer(data=data)
        if questionnaireS.is_valid():
            newQuestionnaire = questionnaireS.save()
            data.clear()
            data = questionnaire.Settings.to_dict(exclude=['id'])
            settingsS = SettingsSerializer(data=data)
            if settingsS.is_valid():
                s = settingsS.save()
                newQuestionnaire.Settings = s
                newQuestionnaire.save()
            else:
                print(settingsS.errors)
            data.clear()
            data['EncodeID'] = encoder.encrypt(str(newQuestionnaire.id))
            questionnaireS = QuestionnaireSerializer(instance=newQuestionnaire, data=data)
            if questionnaireS.is_valid():
                newQuestionnaire = questionnaireS.save()
                for q in questionnaire.Question.all():
                    data.clear()
                    data = q.to_dict()
                    data['Questionnaire'] = newQuestionnaire.id
                    questionS = QuestionSerializer(data=data)
                    if questionS.is_valid():
                        newQuestion = questionS.save()
                        for c in q.Choice.all():
                            data.clear()
                            data = c.to_dict()
                            data['Question'] = newQuestion.id
                            choiceS = ChoiceSerializer(data=data)
                            if choiceS.is_valid():
                                choiceS.save()
                            else:
                                print(choiceS.errors)
                                continue
                    else:
                        print(questionS.errors)
                        continue
            else:
                print(questionnaireS.errors)
                return JsonResponse({"Message": "Encode Failed"}, safe=False)
        else:
            print(questionnaireS.errors)
            return JsonResponse({"Message": "Copy Failed"}, safe=False)
        return JsonResponse({"Questionnaire": newQuestionnaire.to_dict(exclude=['Question']), "Message": "Success"},
                            safe=False)


@csrf_exempt
def exportQuestionnaire(request):
    if request.method == 'POST':
        data = json.loads(request.body)
        if 'id' not in data:
            return JsonResponse({"Message": "Need questionnaire id"}, safe=False)
        qid = data['id']
        username = data.get('username')
        if username:
            try:
                user = User.objects.get(username=username)
            except:
                return JsonResponse({'Message': 'User Does Not Exist'}, safe=False)
        else:
            return JsonResponse({'Message': 'Please Login'}, safe=False)
        try:
            questionnaire = Questionnaire.objects.get(id=qid, CreateUser=user.id)
        except Questionnaire.DoesNotExist:
            return JsonResponse({"Message": "No Such Questionnaire"}, safe=False)
        doc = questionnaire.export()
        response = HttpResponse(content_type='application/vnd.openxmlformats-officedocument.wordprocessingml.document')
        response['Content-Disposition'] = 'attachment; filename=' + questionnaire.EncodeID + '.docx'
        doc.save(response)
        return response


@csrf_exempt
def createQuestion(request):
    if request.method == 'POST':
        data = json.loads(request.body)
        username = data.get('username')
        if username:
            try:
                user = User.objects.get(username=username)
            except:
                return JsonResponse({'Message': 'User Does Not Exist'}, safe=False)
        else:
            return JsonResponse({'Message': 'Please Login'}, safe=False)
        qid = data['Questionnaire']
        try:
            questionnaire = Questionnaire.objects.get(id=qid, CreateUser=user.id)
        except Questionnaire.DoesNotExist:
            return JsonResponse({"Message": "No Such Questionnaire"}, safe=False)
        newQuestion = QuestionSerializer(data=data)
        if newQuestion.is_valid():
            newQuestion = newQuestion.save()
        else:
            print(newQuestion.errors)
            return JsonResponse({"Message": "Arguments Illegal"}, safe=False)
        return JsonResponse({"id": newQuestion.id, "Message": "Success"}, safe=False)


@csrf_exempt
def modifyQuestion(request):
    if request.method == 'POST':
        data = json.loads(request.body)
        if 'id' not in data:
            return JsonResponse({"Message": "Need question id"}, safe=False)
        qid = data['id']
        username = data.get('username')
        if username:
            try:
                user = User.objects.get(username=username)
            except:
                return JsonResponse({'Message': 'User Does Not Exist'}, safe=False)
        else:
            return JsonResponse({'Message': 'Please Login'}, safe=False)
        try:
            question = Question.objects.get(id=qid)
        except Question.DoesNotExist:
            return JsonResponse({"Message": "No Such Question"}, safe=False)
        if question.Questionnaire.CreateUser_id != user.id:
            return JsonResponse({"Message": "User not match"}, safe=False)
        if 'Questionnaire' in data and question.Questionnaire.id != data['Questionnaire']:
            return JsonResponse({"Message": "Questionnaire not match"}, safe=False)
        data['Questionnaire'] = question.Questionnaire.id
        questionS = QuestionSerializer(instance=question, data=data)
        if questionS.is_valid():
            question = questionS.save()
            if 'Choice' not in data:
                return JsonResponse({"Message": "Success"}, safe=False)
            for c in question.Choice.all():
                c.delete()
            for c in data['Choice']:
                if 'id' in c:
                    del c['id']
                c['Question'] = question.id
                choiceS = ChoiceSerializer(data=c)
                if choiceS.is_valid():
                    choiceS.save()
                else:
                    print(choiceS.errors)
                    return JsonResponse({"Message": "Choice Illegal", "Illegal Choice": c}, safe=False)
        else:
            print(questionS.errors)
            return JsonResponse({"Message": "Arguments Illegal"}, safe=False)
        time = {'UpdateTime': timezone.now()}
        questionnaireS = QuestionnaireSerializer(instance=question.Questionnaire, data=time)
        if questionnaireS.is_valid():
            questionnaireS.save()
        else:
            print(questionnaireS.errors)
        return JsonResponse({"Message": "Success"}, safe=False)


@csrf_exempt
def deleteQuestion(request):
    if request.method == 'POST':
        data = json.loads(request.body)
        if 'id' not in data:
            return JsonResponse({"Message": "Need question id"}, safe=False)
        qid = data['id']
        username = data.get('username')
        if username:
            try:
                user = User.objects.get(username=username)
            except:
                return JsonResponse({'Message': 'User Does Not Exist'}, safe=False)
        else:
            return JsonResponse({'Message': 'Please Login'}, safe=False)
        try:
            question = Question.objects.get(id=qid)
        except Question.DoesNotExist:
            return JsonResponse({"Message": "No Such Question"}, safe=False)
        if question.Questionnaire.CreateUser_id != user.id:
            return JsonResponse({"Message": "User not match"}, safe=False)
        question.delete()
        return JsonResponse({"Message": "Success"}, safe=False)


@csrf_exempt
def questionnaireID(request):
    if request.method == 'GET':
        try:
            questionnaire = Questionnaire.objects.get(id=request.GET.get('id'))
        except Questionnaire.DoesNotExist:
            return JsonResponse({"Message": "No Such Questionnaire"}, safe=False)
        return JsonResponse({"Questionnaire": questionnaire.to_dict()}, safe=False)


@csrf_exempt
def questionID(request):
    if request.method == 'GET':
        try:
            question = Question.objects.get(id=request.GET.get('id'))
        except Question.DoesNotExist:
            return JsonResponse({"Message": "No Such Question"}, safe=False)
        return JsonResponse({"Question": question.to_dict()}, safe=False)


@csrf_exempt
def choiceID(request):
    if request.method == 'GET':
        try:
            choice = Choice.objects.get(id=request.GET.get('id'))
        except Choice.DoesNotExist:
            return JsonResponse({"Message": "No Such Choice"}, safe=False)
        return JsonResponse({"Choice": choice.to_dict()}, safe=False)


@csrf_exempt
def releaseQuestionnaire(request):
    if request.method == 'POST':
        data = json.loads(request.body)
        if 'id' not in data:
            return JsonResponse({"Message": "Need questionnaire id"}, safe=False)
        qid = data['id']
        del data['id']
        username = data.get('username')
        if username:
            try:
                user = User.objects.get(username=username)
            except User.DoesNotExist:
                return JsonResponse({'Message': 'User Does Not Exist'}, safe=False)
        else:
            return JsonResponse({'Message': 'Please Login'}, safe=False)
        try:
            questionnaire = Questionnaire.objects.get(id=qid, CreateUser=user.id)
        except Questionnaire.DoesNotExist:
            return JsonResponse({"Message": "No Such Questionnaire"}, safe=False)
        if 'Open' not in data:
            return JsonResponse({"Message": "Need Argument 'Open'"}, safe=False)
        checkQuestionnaireTime(questionnaire)
        if data['Open'] == questionnaire.Open:
            return JsonResponse({"Message": "Success"}, safe=False)
        if not questionnaire.Open:
            data['ReleaseTime'] = timezone.now()
        questionnaireS = QuestionnaireSerializer(instance=questionnaire, data=data)
        if questionnaireS.is_valid():
            questionnaireS.save()
        else:
            print(questionnaireS.errors)
            return JsonResponse({"Message": "Arguments Illegal"}, safe=False)
        return JsonResponse({"Message": "Success"}, safe=False)


@csrf_exempt
def removeQuestionnaire(request):
    if request.method == 'POST':
        data = json.loads(request.body)
        if 'id' not in data:
            return JsonResponse({"Message": "Need questionnaire id"}, safe=False)
        qid = data['id']
        del data['id']
        username = data.get('username')
        if username:
            try:
                user = User.objects.get(username=username)
            except User.DoesNotExist:
                return JsonResponse({'Message': 'User Does Not Exist'}, safe=False)
        else:
            return JsonResponse({'Message': 'Please Login'}, safe=False)
        try:
            questionnaire = Questionnaire.objects.get(id=qid, CreateUser=user.id)
        except Questionnaire.DoesNotExist:
            return JsonResponse({"Message": "No Such Questionnaire"}, safe=False)
        if 'Remove' not in data:
            return JsonResponse({"Message": "Need Argument 'Remove'"}, safe=False)
        questionnaireS = QuestionnaireSerializer(instance=questionnaire, data=data)
        if questionnaireS.is_valid():
            questionnaireS.save()
        else:
            print(questionnaireS.errors)
            return JsonResponse({"Message": "Arguments Illegal"}, safe=False)
        return JsonResponse({"Message": "Success"}, safe=False)


@csrf_exempt
def starQuestionnaire(request):
    if request.method == 'POST':
        data = json.loads(request.body)
        if 'id' not in data:
            return JsonResponse({"Message": "Need questionnaire id"}, safe=False)
        qid = data['id']
        del data['id']
        username = data.get('username')
        if username:
            try:
                user = User.objects.get(username=username)
            except User.DoesNotExist:
                return JsonResponse({'Message': 'User Does Not Exist'}, safe=False)
        else:
            return JsonResponse({'Message': 'Please Login'}, safe=False)
        try:
            questionnaire = Questionnaire.objects.get(id=qid, CreateUser=user.id)
        except Questionnaire.DoesNotExist:
            return JsonResponse({"Message": "No Such Questionnaire"}, safe=False)
        if 'Star' not in data:
            return JsonResponse({"Message": "Need Argument 'Star'"}, safe=False)
        questionnaireS = QuestionnaireSerializer(instance=questionnaire, data=data)
        if questionnaireS.is_valid():
            questionnaireS.save()
        else:
            print(questionnaireS.errors)
            return JsonResponse({"Message": "Arguments Illegal"}, safe=False)
        return JsonResponse({"Message": "Success"}, safe=False)
